home *** CD-ROM | disk | FTP | other *** search
-
- /*© Copyright 1988-1992 UserLand Software, Inc. All Rights Reserved.*/
-
-
- #include "appletops.h"
- #include "appletstrings.h"
- #include "appletmemory.h"
- #include "appletcursor.h"
- #include "appletdialogs.h"
- #include "appletfiles.h"
-
-
- static boolean foldertest (CInfoPBRec *pb) {
-
- /*
- return true if pb holds info describing a folder.
- */
-
- return (BitTst (&pb->dirInfo.ioFlAttrib, 3));
- } /*foldertest*/
-
-
- static boolean getinfofrompb (CInfoPBRec *ppb, tyfileinfo *info) {
-
- CInfoPBRec pb = *ppb;
- boolean flfolder;
-
- (*info).fllocked = BitTst (&pb.dirInfo.ioFlAttrib, 7);
-
- flfolder = (*info).flfolder = foldertest (&pb);
-
- if (flfolder) {
-
- (*info).flbusy = pb.dirInfo.ioDrNmFls > 0;
-
- (*info).filecreator = (*info).filetype = ' ';
-
- (*info).timecreated = pb.dirInfo.ioDrCrDat;
-
- (*info).timemodified = pb.dirInfo.ioDrMdDat;
-
- (*info).iconposition = pb.dirInfo.ioDrUsrWds.frLocation;
- }
-
- else { /*fill in fields for a file, somewhat different format than a folder*/
-
- (*info).flbusy = BitTst (&pb.hFileInfo.ioFlAttrib, 0);
-
- (*info).flbundle = (pb.hFileInfo.ioFlFndrInfo.fdFlags & 0x2000) != 0;
-
- (*info).flinvisible = (pb.hFileInfo.ioFlFndrInfo.fdFlags & 0x4000) != 0;
-
- (*info).flalias = (pb.hFileInfo.ioFlFndrInfo.fdFlags & 0x8000) != 0;
-
- (*info).filecreator = pb.hFileInfo.ioFlFndrInfo.fdCreator;
-
- (*info).filetype = pb.hFileInfo.ioFlFndrInfo.fdType;
-
- (*info).timecreated = pb.hFileInfo.ioFlCrDat;
-
- (*info).timemodified = pb.hFileInfo.ioFlMdDat;
-
- (*info).sizedatafork = pb.hFileInfo.ioFlLgLen;
-
- (*info).sizeresourcefork = pb.hFileInfo.ioFlRLgLen;
-
- (*info).iconposition = pb.hFileInfo.ioFlFndrInfo.fdLocation;
- }
-
- (*info).ixlabel = (pb.hFileInfo.ioFlFndrInfo.fdFlags & 0x000E) >> 1;
-
- return (true);
- } /*getinfofrompb*/
-
-
- boolean filegetinfo (bigstring fname, short vnum, tyfileinfo *info) {
-
- CInfoPBRec pb;
-
- clearbytes (&pb, longsizeof (pb)); /*init all fields to zero*/
-
- pb.hFileInfo.ioNamePtr = fname;
-
- pb.hFileInfo.ioVRefNum = vnum;
-
- (*info).errcode = PBGetCatInfo (&pb, false);
-
- if ((*info).errcode != noErr)
- return (false);
-
- clearbytes (info, longsizeof (tyfileinfo)); /*init all fields to zero*/
-
- copystring (fname, (*info).fname);
-
- getinfofrompb (&pb, info);
-
- return (true);
- } /*filegetinfo*/
-
-
- boolean filedelete (bigstring bspath, short vnum) {
-
- HParamBlockRec pb;
-
- clearbytes (&pb, longsizeof (pb));
-
- pb.ioParam.ioNamePtr = bspath;
-
- pb.ioParam.ioVRefNum = vnum;
-
- return (PBHDelete (&pb, false) == noErr);
- } /*filedelete*/
-
-
- void fileclose (short fnum) {
-
- if (fnum != 0)
- FSClose (fnum);
- } /*fileclose*/
-
-
- boolean fileseteof (short fnum, long eof) {
-
- OSErr errcode;
-
- if (fnum != 0) {
-
- errcode = SetEOF (fnum, eof);
-
- return (errcode == noErr);
- }
-
- return (true);
- } /*fileseteof*/
-
-
- boolean fileopenorcreate (bigstring bs, short vnum, OSType creator, OSType filetype, short *fnum) {
-
- /*
- open or create a file indicated by bs and vnum. if bs is a full path,
- set vnum to 0. return with fnum set to the Mac filesystem's file number
- for the file.
-
- if we open a file, we takes what we get in the creator and filetype department.
- however, if we create a file it's of the indicated filetype and creator.
- */
-
- if (FSOpen (bs, vnum, fnum) == noErr) /*file exists and is open*/
- return (true);
-
- if (Create (bs, vnum, creator, filetype) != noErr)
- return (false);
-
- if (FSOpen (bs, vnum, fnum) != noErr) {
-
- FSClose (*fnum);
-
- filedelete (bs, vnum);
-
- return (false); /*failed to open the file for writing*/
- }
-
- return (true);
- } /*fileopenorcreate*/
-
-
- boolean fileopen (bigstring bs, short vnum, short *fnum) {
-
- register OSErr ec;
-
- ec = FSOpen (bs, vnum, fnum);
-
- return (ec == noErr);
- } /*fileopen*/
-
-
- boolean filenew (bigstring bsfname, short vnum, OSType creator, OSType filetype, short *fnum) {
-
- register OSErr errcode;
-
- if (FSOpen (bsfname, vnum, fnum) == noErr) { /*file exists, delete it*/
-
- FSClose (*fnum);
-
- filedelete (bsfname, vnum);
- }
-
- errcode = Create (bsfname, vnum, creator, filetype);
-
- if (oserror (errcode)) /*failed to open the file for writing*/
- return (false);
-
- errcode = FSOpen (bsfname, vnum, fnum);
-
- if (oserror (errcode)) {
-
- FSClose (*fnum);
-
- filedelete (bsfname, vnum);
-
- return (false); /*failed to open the file for writing*/
- }
-
- return (true); /*file exists and its open*/
- } /*filenew*/
-
-
- boolean filetruncate (short fnum) {
-
- return (SetEOF (fnum, 0) == noErr);
- } /*filetruncate*/
-
-
- long filegetsize (short fnum) {
-
- /*
- get the size of a file that's already open.
- */
-
- long filesize;
-
- if (GetEOF (fnum, &filesize) != noErr)
- filesize = 0;
-
- return (filesize);
- } /*filegetsize*/
-
-
- boolean filewrite (short fnum, long ctwrite, void *buffer) {
-
- /*
- write ctwrite bytes from buffer to the current position in file number
- fnum. return true iff successful.
- */
-
- if (ctwrite > 0)
-
- if (FSWrite (fnum, &ctwrite, buffer) != noErr)
-
- return (false);
-
- return (true);
- } /*filewrite*/
-
-
- boolean fileread (short fnum, long ctread, void *buffer) {
-
- /*
- read ctread bytes from the current position in file number fnum into
- the buffer. return true iff successful.
- */
-
- if (ctread > 0)
-
- if (oserror (FSRead (fnum, &ctread, buffer)))
-
- return (false);
-
- return (true);
- } /*fileread*/
-
-
- boolean filegetchar (short fnum, byte *buffer) {
-
- /*
- read the next character from the indicated file, returning it in *buffer.
-
- return false if we're at the end of the file, without triggering an error
- dialog.
- */
-
- long fpos, eof;
-
- if (GetFPos (fnum, &fpos) != noErr)
- return (false);
-
- if (GetEOF (fnum, &eof) != noErr)
- return (false);
-
- if (fpos == eof)
- return (false);
-
- if (!fileread (fnum, 1L, buffer))
- return (false);
-
- return (true);
- } /*filegetchar*/
-
-
- boolean filewritehandle (short fnum, Handle h) {
-
- /*
- write the indicated handle to the open file indicated by fnum at the
- current position in the file.
- */
-
- return (filewrite (fnum, GetHandleSize (h), *h));
- } /*filewritehandle*/
-
-
- boolean filereadhandle (short fnum, long ctbytes, Handle *hreturned) {
-
- Handle h;
- boolean fl;
-
- if (!newclearhandle (ctbytes, hreturned))
- return (false);
-
- h = *hreturned; /*copy into register*/
-
- lockhandle (h);
-
- fl = fileread (fnum, ctbytes, *h);
-
- unlockhandle (h);
-
- if (!fl) {
-
- disposehandle (h);
-
- *hreturned = nil;
-
- return (false);
- }
-
- return (true);
- } /*filereadhandle*/
-
-
- boolean filereadwholefile (short fnum, Handle *hreturned) {
-
- /*
- load the whole file into memory, return true if it worked, with
- the handle holding all the data from the file.
- */
-
- return (filereadhandle (fnum, filegetsize (fnum), hreturned));
- } /*filereadwholefile*/
-
-
- boolean fileparsevolname (bspath, vnum) bigstring bspath; short *vnum; {
-
- /*
- convert a full path, which might contain a volume name at the beginning
- to a path with no volume name, and it's associated volume number in vnum.
-
- example: "Rover™:MORE Work" will return with bspath = "MORE Work" and
- vnum = -2 (the Macintosh vrefnum for the second mounted drive).
-
- this combination of information plugs nicely into a lot of the file
- manager routines.
- */
-
- short ix = 1;
- bigstring bsvolname;
- HParamBlockRec pb;
- short vrefnum;
- bigstring bs;
-
- copystring (bspath, bs); /*work on a copy*/
-
- if (isemptystring (bs))
- return (false);
-
- if (!scanstring (':', bs, &ix)) { /*no colon, the whole thing is a volname*/
-
- copystring (bs, bsvolname);
-
- pushchar (':', bsvolname);
-
- setemptystring (bs);
- }
- else {
- midstring (bs, 1, ix, bsvolname); /*pick off the vol name and the colon*/
-
- deletestring (bs, 1, ix);
- }
-
- clearbytes (&pb, longsizeof (pb));
-
- pb.volumeParam.ioNamePtr = bsvolname;
-
- pb.volumeParam.ioVolIndex = -1; /*force him to use the name pointer only*/
-
- if (PBGetVInfo ((ParmBlkPtr) &pb, false) != noErr)
- return (false);
-
- *vnum = pb.volumeParam.ioVRefNum;
-
- return (true);
- } /*fileparsevolname*/
-
-
- boolean filefrompath (path, fname) bigstring path, fname; {
-
- /*
- return all the characters to the right of the last colon in the path.
-
- example: "Work Disk #1:MORE Work:Status Center" returns "Status Center".
- */
-
- bigstring bs;
- short len;
- boolean flpushcolon = false;
-
- copystring (path, bs); /*work on a copy, we might modify it*/
-
- len = stringlength (bs);
-
- if (len <= 0) {
-
- setstringlength (fname, 0);
-
- return (true);
- }
-
- if (bs [len] == ':') {
-
- setstringlength (bs, len - 1);
-
- flpushcolon = true;
- }
-
- lastword (bs, ':', fname);
-
- if (flpushcolon)
- pushchar (':', fname);
-
- return (true);
- } /*filefrompath*/
-
-
- boolean folderfrompath (path, folder) bigstring path, folder; {
-
- /*
- return all the characters to the left of the colon, and the colon.
-
- example: "Work Disk #1:MORE Work:Status Center" returns "Work Disk #1:MORE Work:".
- */
-
- bigstring bs;
-
- lastword (path, ':', bs); /*kind of inefficient, but ensures symmetry*/
-
- copystring (path, folder);
-
- setstringlength (folder, stringlength (folder) - stringlength (bs));
-
- return (true);
- } /*folderfrompath*/
-
-
- boolean pathtofileinfo (path, fname, vnum) bigstring path, fname; short *vnum; {
-
- /*
- convert a Macintosh file path into a file name and a volume number.
-
- we also get the directory id of the parent directory, primarily because we
- have the code here, it supposedly works, and we might need it someday.
- */
-
- CInfoPBRec pb;
- bigstring folder;
- long idparent;
-
- if (!fileparsevolname (path, vnum)) /*no volume specified*/
- return (false);
-
- folderfrompath (path, folder);
-
- filefrompath (path, fname);
-
- clearbytes (&pb, longsizeof (pb));
-
- pb.dirInfo.ioNamePtr = folder;
-
- if (PBGetCatInfo (&pb,false) != noErr)
- return (false);
-
- if (BitTst (&pb.hFileInfo.ioFlAttrib, 3)) /*it's a folder*/
- idparent = pb.dirInfo.ioDrDirID;
- else
- idparent = pb.hFileInfo.ioFlParID;
-
- return (true);
- } /*pathtofileinfo*/
-
-
- boolean directorytopath (long DirID, short vnum, bigstring path) {
-
- CInfoPBRec block;
- bigstring bsdirectory;
- OSErr errcode;
-
- setemptystring (path);
-
- clearbytes (&block, longsizeof (block));
-
- block.dirInfo.ioNamePtr = bsdirectory;
-
- block.dirInfo.ioDrParID = DirID;
-
- do {
- block.dirInfo.ioVRefNum = vnum;
-
- block.dirInfo.ioFDirIndex = -1;
-
- block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID;
-
- errcode = PBGetCatInfo(&block,false);
-
- if (errcode != noErr)
- return (false);
-
- if (!pushchar (':', bsdirectory))
- return (false);
-
- if (!pushstring (path, bsdirectory))
- return (false);
-
- copystring (bsdirectory, path);
- } while (block.dirInfo.ioDrDirID != fsRtDirID);
-
- return (true);
- } /*directorytopath*/
-
-
- static boolean PathNameFromWD (long vnum, bigstring path) {
-
- /*
- PBGetWDInfo has a bug under A/UX 1.1. If vnum is a real vnum
- and not a wdRefNum, then it returns garbage. Since A/UX has only 1
- volume (in the Macintosh sense) and only 1 root directory, this can
- occur only when a file has been selected in the root directory (/).
- So we look for this and hard code the DirID and vnum.
- */
-
- WDPBRec block;
-
- clearbytes (&block, longsizeof (block));
-
- block.ioVRefNum = vnum;
-
- PBGetWDInfo (&block,false);
-
- return (directorytopath (block.ioWDDirID,block.ioWDVRefNum,path));
- } /*PathNameFromWD*/
-
-
- boolean fileinfotopath (bigstring fname, short vnum, bigstring path) {
-
- setemptystring (path);
-
- if (!PathNameFromWD ((long) vnum, path))
- return (false);
-
- pushstring (fname, path);
-
- return (true);
- } /*fileinfotopath*/
-
-
- static sfcallback sfglobalfilter = nil;
-
-
- static pascal Boolean sffilter (CInfoPBRec *pb) {
-
- /*
- if we return true, the file is filtered, meaning it is not included in the
- standard file dialog list.
- */
-
- tyfileinfo info;
-
- if (sfglobalfilter == nil)
- return (-1);
-
- clearbytes (&info, longsizeof (tyfileinfo)); /*init all fields to zero*/
-
- copystring ((*pb).hFileInfo.ioNamePtr, info.fname);
-
- getinfofrompb (pb, &info);
-
- if ((*sfglobalfilter) (&info))
- return (-1);
-
- return (0);
- } /*sffilter*/
-
-
- boolean sfdialog (boolean flput, bigstring fname, short *vnum, sfcallback filterproc, OSType filetype) {
-
- register DialogTHndl hdialog;
- register short id;
- Rect r, rscreen;
- Point pt;
- SFReply reply;
- SFTypeList typesrec;
-
- cometofront ();
-
- arrowcursor ();
-
- if (flput)
- id = getDlgID;
- else
- id = putDlgID;
-
- hdialog = (DialogTHndl) GetResource ('DLOG', id);
-
- if (hdialog == nil) {
-
- pt.h = pt.v = 85;
- }
- else {
- r = (**hdialog).boundsRect;
-
- rscreen = quickdrawglobal (screenBits).bounds;
-
- pt.h = rscreen.left + (((rscreen.right - rscreen.left) - (r.right - r.left)) / 2);
-
- pt.v = rscreen.top + ((rscreen.bottom - rscreen.top) - (r.bottom - r.top)) / 3;
- }
-
- if (flput)
- SFPutFile (pt, (ptrstring) "\p", fname, nil, &reply);
-
- else {
- short ctfiles;
-
- if (filetype == 0) /*set filetype to 0 to get all files*/
- ctfiles = -1;
- else {
- ctfiles = 1;
-
- typesrec [0] = filetype;
- }
-
- if (filterproc == nil) {
-
- SFGetFile (pt, (ptrstring) "\p", nil, ctfiles, typesrec, nil, &reply);
- }
- else {
- sfglobalfilter = filterproc;
-
- SFGetFile (pt, (ptrstring) "\p", (FileFilterProcPtr) &sffilter, ctfiles, typesrec, nil, &reply);
- }
- }
-
- if (reply.good) {
-
- *vnum = reply.vRefNum;
-
- copystring (reply.fName, fname);
- }
-
- return (reply.good);
- } /*sfdialog*/
-
-
-